#ifndef GSTREAMER_PIPELINE_H
#define GSTREAMER_PIPELINE_H

#include <QObject>
#include <QImage>
#include <functional>
#include <gst/gst.h>
#include <gst/app/gstappsink.h>

// 定义帧数据结构，使用原始指针
struct FrameData {
    const uchar* data;        // 指向图像数据的指针
    int width;                // 图像宽度
    int height;               // 图像高度
    QImage::Format format;    // 图像格式
    std::function<void()> cleanup; // 清理函数
    
    FrameData(const uchar* d = nullptr, int w = 0, int h = 0, 
              QImage::Format f = QImage::Format_Invalid, 
              std::function<void()> c = nullptr)
        : data(d), width(w), height(h), format(f), cleanup(c) {}
    
    bool isValid() const {
        return data != nullptr && width > 0 && height > 0 && format != QImage::Format_Invalid;
    }
};
Q_DECLARE_METATYPE(FrameData)

class GStreamerPipeline : public QObject
{
    Q_OBJECT

public:

    explicit GStreamerPipeline(QObject *parent = nullptr);
    ~GStreamerPipeline();

    bool initializePipeline(const QString &device = "/dev/video0", 
                           int width = 640, int height = 480, int fps = 30);
    bool startPipeline();
    void stopPipeline();
    bool isRunning() const;

    // 录制功能
    bool startRecording(const QString& filename);
    bool stopRecording();
    bool isRecording() const;

    // 推流功能
    bool startStreaming(const QString& streamUrl);
    bool stopStreaming();
    bool isStreaming() const;
     

signals:
    void newFrameDataAvailable(const FrameData &frameData);
    void errorOccurred(const QString &errorMessage);
    
    // 录制信号
    void recordingStarted();
    void recordingStopped();
    // 推流信号
    void streamingStarted();
    void streamingStopped();


private:
    static GstFlowReturn onNewSample(GstAppSink *appsink, gpointer user_data);
    GstFlowReturn handleNewSample(GstAppSink *appsink);
 void cleanupRecordingElements();
void cleanupStreamingElements();


    GstElement *m_pipeline;
    GstElement *m_appSink;
    GstElement *m_tee;           // tee元素用于分流
    
    // 视频分支
    GstElement *m_recordQueue;
    GstElement *m_recordEncoder;
    GstElement *m_recordMuxer;
    GstElement *m_recordSink;
    GstPad *m_recordTeePad;
    
    // 音频
    GstElement *m_audioSource;
    GstElement *m_audioQueue;
    GstElement *m_audioConvert;
    GstElement *m_audioResample;
    GstElement *m_audioEncoder;
    GstPad *m_audioTeePad;

    // 推流分支
    GstElement *m_streamQueue;
    GstElement *m_streamEncoder;
    GstElement *m_streamSink;
    GstPad *m_streamTeePad;

    int m_width;
    int m_height;
    int m_fps;
    bool m_isRunning;

    bool m_isRecording;
    bool m_isStreaming;
    QString m_currentOutputPath;
    QString m_currentStreamUrl;
    bool m_waitingForRecordingEOS;
};

#endif // GSTREAMER_PIPELINE_H